/*
 * @Date: 2024-06-30 20:59:48
 * @LastEditors: wkl
 * @LastEditTime: 2024-07-22 09:19:28
 * @FilePath: /keep-nest/src/box/box.controller.ts
 */
import { Controller, Get, Post, Request, Response } from '@nestjs/common';
import { getSignature, decrypt, encrypt } from '@wecom/crypto';
import { join } from 'path';
import { get } from 'https';
import { createWriteStream, unlink } from 'fs';
import * as getRawBody from 'raw-body';
import * as xml2js from 'xml2js';
import axios from 'axios';

const config: any = {
  agentId: 1000003,

  token: 'q2Y9baMYA1ACraulWJn5kqHJdGRLUhNT',

  appid: 'ww66c831ca4e123a58',

  encodingAESKey: 'trPRLMIpo5Lm5wjVBAyG7l7Wr6vOKIm5qmsyNnxwdMb',

  Secret: 'vNCnSrFsMed_4hs3td2gjDs3u3121N-8cqMK01o9mYs',

  bot_id: '7387704691595018292',

  user: '7385553380237672502',

  Authorization:
    'pat_eo0gxNbslaQ0VWAS66l1nemOFQMdeWslx46mmhjk7mugdjbou5gbqmmn3Pir8w6l',
};

@Controller()
export class BoxController {
  constructor() {}

  // 对接ai
  aiFun(query, config, toUsername, mediaId) {
    const data = JSON.stringify({
      bot_id: config.bot_id,
      user: config.user,
      query: query,
      stream: false,
    });

    const configAxios = {
      method: 'post',
      url: 'https://api.coze.cn/open_api/v2/chat',
      headers: {
        Authorization: `Bearer ${config.Authorization}`,
        Accept: '*/*',
        Connection: 'keep-alive',
        'Content-Type': 'application/json',
      },
      data: data,
    };
    return new Promise((resolve, reject) => {
      axios(configAxios)
        .then((response) => {
          console.log(response.data, 'response.data.messages62');
          const messages = response.data.messages.filter(
            (item) => item.type == 'answer',
          );
          console.log(messages[0].content, 'messages[0].content145');
          if (mediaId) {
            const folderPath = join(
              __dirname,
              `../static/${mediaId}_${config.agentId}file.amr`,
            );
            unlink(folderPath, (err) => {
              if (err) throw err;
              console.log('文件已删除');
            });
          }

          this.sendAppMes(messages[0].content, toUsername);
          resolve(messages[0].content);
        })
        .catch(function (error) {
          reject(error);
        });
    });
  }

  // 获取accessToken
  // https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=ID&corpsecret=SECRET
  accessToken() {
    const configAxios = {
      method: 'get',
      url: `https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid=${config.appid}&corpsecret=${config.Secret}`,
    };

    return new Promise(function (resolve, reject) {
      axios(configAxios)
        .then(function (response) {
          console.log(response.data, '204');
          resolve(response.data);
        })
        .catch(function (error) {
          console.log(error);
          reject(error);
        });
    });
  }
  // 语音文件获取ajax
  aiFunVoice(ACCESS_TOKEN, MEDIA_ID) {
    // 假设这是AMR文件的URL
    const amrUrl = `https://qyapi.weixin.qq.com/cgi-bin/media/get?access_token=${ACCESS_TOKEN}&media_id=${MEDIA_ID}`;

    // 创建HTTP GET请求来获取AMR文件
    let folderPath = join(
      __dirname,
      `../static/${MEDIA_ID}_${config.agentId}file.amr`,
    );
    folderPath = folderPath.replace('/dist', '');
    console.log(folderPath, 'folderPath');
    const file = createWriteStream(folderPath);
    get(amrUrl, (response) => {
      response.pipe(file);
      file.on('finish', () => {
        file.close();
        console.log('AMR file downloaded and saved.');
      });
    });
  }

  async getVoice(MediaId) {
    const res: any = await this.accessToken();
    await this.aiFunVoice(res.access_token, MediaId[0]);
  }

  // 发送应用消息
  async sendAppMes(data, toUsername) {
    const res: any = await this.accessToken();
    console.log(res, '247');
    const obj = {
      touser: toUsername,
      toparty: '',
      msgtype: 'text',
      agentid: config.agentId,
      text: {
        content: data,
      },
      safe: 0,
      enable_id_trans: 0,
      enable_duplicate_check: 0,
      duplicate_check_interval: 1800,
    };
    const configAxios: any = {
      method: 'post',
      url: `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${res.access_token}`,
      data: obj,
    };

    return new Promise(function (resolve, reject) {
      axios(configAxios)
        .then(function (response) {
          console.log(response.data, '270');
          resolve(response.data);
        })
        .catch(function (error) {
          console.log(error);
          reject(error);
        });
    });
  }

  //箱证接口处理
  cerInquireFun(transactionNo) {
    const data = JSON.stringify({
      transactionNo: transactionNo,
      status: 'Success',
      pageNo: 1,
      pageSize: 10,
    });

    const config = {
      method: 'post',
      url: '/sone-ctm/api/v0/cert-inquire/query-unit-cert-list',
      headers: {
        Authorization:
          'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjb3VudHJ5IjpudWxsLCJjaGFuZ2VQd2RUaW1lIjpudWxsLCJjaXR5IjpudWxsLCJ1c2VyX25hbWUiOiJPUFNCQVRDSCIsIm9wZW5JZCI6bnVsbCwiY29tcGFueU5hbWUiOiJGbG9yZW5zIEFzc2V0IE1hbmFnZW1lbnQgQ29tcGFueSBMaW1pdGVkIiwiZHVlRGF0ZSI6bnVsbCwibGFuZ3VhZ2UiOm51bGwsImNsaWVudF9pZCI6InNvQ3ViUDQzdUo5dSIsImVuYWJsZWQiOnRydWUsInVzZXJDb2RlIjoiT1BTQkFUQ0giLCJvZmZpY2VUZWwiOm51bGwsInBhc3N3b3JkIjpudWxsLCJwb3N0IjpudWxsLCJwcm92aW5jZSI6bnVsbCwic2NvcGUiOlsicmFtIl0sImNyZXdBcHAiOm51bGwsImxvZ2luTmFtZSI6Ik9QU0JBVENIIiwibmlja25hbWUiOm51bGwsImJhY2tlbmQiOjAsImlkIjoiTlRna0tlWnRFRjZWMjRubVB3NVNkeSIsImV4cCI6MTcxOTkxODE2NCwianRpIjoiYzEwMzBhMzMtMjFkMS00NTI4LThjNjgtNzZjOTJmNmFmM2Q2IiwiZW1haWwiOm51bGwsImFjY291bnROb25Mb2NrZWQiOnRydWUsIm5lZWRJbml0UGFzc3dvcmQiOjEsImNvbXBhbnlBZGRyIjpudWxsLCJjcmVkZW50aWFsc05vbkV4cGlyZWQiOmZhbHNlLCJzZXgiOiJPVEhFUiIsIm1vYmlsZSI6bnVsbCwib2ZmaWNlQ29kZSI6bnVsbCwibmFtZUNuIjoiT1BTQkFUQ0giLCJ1c2VySWQiOiJOVGdrS2VadEVGNlYyNG5tUHc1U2R5IiwiYXV0aG9yaXRpZXMiOlt7ImF1dGhvcml0eSI6IlVTRVIifV0sImNvbXBhbnlJZCI6IlhkUXBjdWhQSnJ0M1dNWUZ1dmtpdkwiLCJkZWxldGVkIjowLCJhY2NvdW50Tm9uRXhwaXJlZCI6dHJ1ZSwiZGV2ZWxvcGVyIjpudWxsLCJtZW1iZXJUeXBlIjpudWxsLCJoZWFkaW1nVXJsIjpudWxsLCJzdGF0dXMiOjAsInVzZXJuYW1lIjoiT1BTQkFUQ0gifQ.Z_scLZ1YnpXZxR0hAm4S1gDyTlDPcz9wfSyikfP112E',
        Pragma: 'no-cache',
        language: 'zh-CN',
        Cookie:
          'SignOnDefault=OPSBATCH; HPTabName=DEFAULT; HPTabNameRemote=; LastActiveTab=DEFAULT; JSESSIONID=5164BF4CFD057520C08D873C74E0F331; ExpirePage=; PS_TOKEN=; PS_DEVICEFEATURES=; psback=; ps_theme=; PS_LOGINLIST=-1; PS_TOKENEXPIRE=-1; pswebsrv2-10000-PORTAL-PSJSESSIONID=d-Vx71yj3zo89BmN8MOI8SejRT4o2MCd!-421334103',
        'User-Agent': 'Apifox/1.0.0 (https://apifox.com)',
        'Content-Type': 'application/json',
      },
      data: data,
    };

    return new Promise(function (resolve, reject) {
      axios(config)
        .then((response) => {
          let str = ' ';
          console.log(JSON.stringify(response.data), '====');
          response.data.data.content.map((item) => {
            if (!item.fileKey) {
              item.fileKey = '';
            }
            str +=
              '箱号为' +
              transactionNo +
              '相关连附件' +
              item.fileKey +
              '\n\r' +
              '动态:.cn/official-app/unitInquiry?UNIT_ID_FZ=' +
              transactionNo;
          });
          console.log(str, '====357');
          resolve(str);
        })
        .catch(function (error) {
          reject(error);
        });
    });
  }
  //xml 处理
  xml2jsFun(xml) {
    return new Promise(function (resolve, reject) {
      xml2js.parseString(
        xml,
        {
          trim: true,
        },
        (err, result) => {
          if (err) {
            reject();
          } else {
            resolve(result);
          }
        },
      );
    });
  }

  //不同类型处理
  async msgTypeFun(msgType, message, fromUsername, toUsername) {
    switch (msgType) {
      case 'text':
        (this as any).aiFun(message.Content[0], config, toUsername);
        break;
      //其他逻辑根据业务需求进行处理
      case 'image':
        console.log('image', '355=====');
        break;
      case 'video':
        break;
      case 'voice':
        this.getVoice(message.MediaId);
        const result = `http://47.121.182.221/static/${message.MediaId[0]}_${config.agentId}file.amr`;
        console.log(result, '379');
        this.aiFun(result, config, toUsername, message.MediaId[0]);
        break;
      case 'location':
        break;
      case 'link':
        break;
      case 'event':
        const event: any = message.Event;
        console.log(event);
        break;
    }
  }

  @Get('/wechat/box')
  getQW(@Request() req, @Response() res) {
    const { msg_signature, timestamp, nonce, echostr } = req.query;
    const signature = getSignature(config.token, timestamp, nonce, echostr);
    // 校验签名是否正确
    if (signature === msg_signature) {
      console.info('签名验证成功');
      // 如果签名校验正确，解密 message
      const { message } = decrypt(config.encodingAESKey, echostr);
      // 返回 message 信息
      res.send(message);
    }
  }

  @Post('/wechat/box')
  async sendMeg(@Request() req, @Response() res) {
    const wholeXML = await getRawBody(req, {
      length: req.headers['content-length'],
      limit: '1mb',
      encoding: 'utf-8',
    });
    // 将 xml 解析成 json
    let formatJson: any = await this.xml2jsFun(wholeXML);
    formatJson = JSON.parse(JSON.stringify(formatJson, null, 4));
    // 得到加密消息体
    const encryptResult = formatJson.xml.Encrypt[0];

    // 将加密消息体进行解密，解密后仍旧是 xml 字符串
    const messageXML = decrypt(config.encodingAESKey, encryptResult);
    // 把解密后 xml 消息体字符串，解析成 json
    const callbackDataBody: any = await this.xml2jsFun(messageXML.message);
    const message = callbackDataBody.xml;
    const fromUsername = message.ToUserName[0];
    const toUsername = message.FromUserName[0];
    const msgType = message.MsgType[0];
    await this.msgTypeFun(msgType, message, fromUsername, toUsername);
    res.status(200).end('success');
  }
}